﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Configuration;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using LynxWiki.DomainModel;
using LynxWiki.Repository;
using LynxWiki.Search;

namespace IronWiki
{
    [Description("A class that provides search capabilities to wiki topic data")]
    public class WikiSearch
    {
        private List<WikiSearchData> _wikiSearch(string qry, string fld = "", int rtnCnt = 0)
        {
            List<SearchData> sdl;
            if (rtnCnt == 0) {
                sdl = LuceneSearch.Search(qry, fld).ToList();
            }
            else {
                sdl = LuceneSearch.Search(qry, fld).Take(rtnCnt).ToList();
            }
            List<WikiSearchData> wsdl = new List<WikiSearchData>();
            foreach (SearchData item in sdl) {
                wsdl.Add(new WikiSearchData(item));
            }
            return wsdl;
        }

        [Description("Search the Creator field for specific value and optionally limit the number of items returned.")]
        public List<WikiSearchData> SearchCreator(string qry, int rtnCnt = 0)
        {
            return _wikiSearch(qry, "Creator", rtnCnt);
        }

        [Description("Search wikiText field for property specificed - this is not an exact return set")]
        public List<WikiSearchData> SearchForProperty(string qry, int rtnCnt = 0)
        {
            return _wikiSearch(qry, "WikiText", rtnCnt);
        }

        [Description("Search Tags field for a specificed value")]
        public List<WikiSearchData> SearchForTag(string qry, int rtnCnt = 0)
        {
            return _wikiSearch(qry, "Tags", rtnCnt);
        }

        [Description("Retrieves a list of WikiTopics from the wiki repository that have a property specified")]
        public List<TopicVersion> GetTopicsWithProperty(string propName)
        {
            string wikiPath = ConfigurationManager.AppSettings["HostWikiPath"];

            WikiSearch ws = new WikiSearch();
            List<WikiSearchData> wsd = ws.SearchForProperty(propName);

            string tempWikiDir = "";
            List<TopicVersion> tList = new List<TopicVersion>();
            WikiTopicRepository wtr = null;
            foreach (WikiSearchData item in wsd) {
                if (!string.Equals(tempWikiDir, item.WikiDir)) {
                    wtr = new WikiTopicRepository(Path.Combine(wikiPath, item.WikiDir.Replace("/", "\\")));
                    tempWikiDir = item.WikiDir;
                }
                TopicVersion tv = wtr.GetCurrentVersion(item.TopicName);
                if (tv.Properties != null) {
                    if (tv.Properties.ContainsKey(propName)) {
                        tList.Add(tv);
                    }
                }
            }
            return tList;
        }

    }

    [Description("A class to return values from the search functions")]
    public class WikiSearchData
    {

        [Description("An identifier for the item")]
        public string ID { get; set; } /* ID includes TopicName and WikiDir in the index */
        [Description("The topic name returned from the search query")]
        public string TopicName { get; set; }
        [Description("The wikidir returned from the search query")]
        public string WikiDir { get; set; }
        [Description("The creator returned from the search query")]
        public string Creator { get; set; }
        [Description("The date the topic was created on returned from the search query")]
        public DateTime CreatedOn { get; set; }
        [Description("The wikitext returned from the search query")]
        public string WikiText { get; set; }
        [Description("The comma-separated tag list returned from the search query")]
        public string Tags { get; set; }  /* each tag is space separated */
        [Description("The document type returned from the search query")]
        public string Type { get; set; }

        public WikiSearchData(SearchData sd)
        {
            ID = sd.ID;
            TopicName = sd.TopicName;
            WikiDir = sd.WikiDir;
            Creator = sd.Creator;
            CreatedOn = sd.CreatedOn;
            WikiText = sd.WikiText;
            Tags = sd.Tags;
            Type = sd.Type;
        }

    }
}
